"""Controller for Pluster system"""

from MVC.plstcontroller import IController
from MVC.plstdocument import IDocument
from MVC.vb_tk import VBtk
from MVC.taskList import *
from MVC.nodeList import *
from service.pconfig import PConfig
from service.task import *
from service.XMLRPC import *
from service.MainServer import MainServer
from service.PlusterLog import *
from service.Log import *
from service.rrd import Rrd
from localEnv import *
from threading import Event
import Tix
import os.path
import signal
import socket
import os



class Controller(IController,PlusterLog,VBtk):
    """Pluster Controller create base object of Pluster and handle
    request from UI, pass them to Adapter"""
    def __init__(self):
        PlusterLog.__init__(self)
        IController.__init__(self)
        self.config=PConfig()
        self.rrd=Rrd()
        self.root=Tix.Tk()
        self.root.protocol('WM_DELETE_WINDOW', self.delete_window)
        self.LoadFrm("Form1.frm",self.root)
        addr=get_ip(self.config.ms_net)
        rpc_port=self.config.port_start
        pool_size=self.config.pool_size
        self.xmlrpcDaemon=XMLRPC(addr,rpc_port,pool_size)
        #------------------init Doc--------------
        self.taskManager=TaskM(self.root)
        self.mainDoc=MainServer("http://"+addr)
        self.logDoc=LogDoc()

        #------------------init Adapter----------
        self.taskAdapter=TaskListAdapter(self.taskManager)
        self.nodeAdapter=NodeListAdapter(self.mainDoc)

        #------------------init view-------------
        self.taskView=TaskListView(self.taskAdapter,self.root)
        self.nodeView=NodeListView(self.nodeAdapter,self.root)
        self.logView=LogView(self.root)
        signal.signal(signal.SIGINT,self.sig_handler)
        signal.signal(signal.SIGTERM,self.sig_handler)

    def delete_window(self):
        print "Pluster Close"
        self.update_event.set()
        rrd=self.config.rrd_path
        if os.path.exists(rrd+'node'):
            os.remove(rrd+'node')
        node_file=open(rrd+'node','w')
        print "Writing connected node info to ",rrd+"node"
        try:
            for node in self.mainDoc.node_list.values():
                addr='http://'+node.get_ip()+':'+str(node.get_port())
                node_file.write(addr+'\n')
        except OSError:
            print 'Can not write file ',rrd+'node'
        node_file.close()
        self.root.quit()



    def Setup(self):
        self.CheckEnv()
        self.taskManager.AddObserver(self.taskView)
        self.mainDoc.AddObserver(self.nodeView)
        self.logDoc.AddObserver(self.logView)
        self.Bind(self.taskView,self.taskAdapter)
        self.Bind(self.nodeView,self.nodeAdapter)

    def Start(self):
        self.mainDoc.Flush()
        self.taskManager.Flush()
        self.logDoc.StartViewLog()
        task=self.taskManager.load_task("Update")
        self.update_event=Event()
        task.config(self.update_event)
        task.start()
        self.reconnect_node()
        self.root.mainloop()

    def reconnect_node (self):
        """ Check node file and reconnect nodes when pluster start"""
        rrd=self.config.rrd_path
        if os.path.exists(rrd+'node'):
            self.log.info("Connect Old Node")
            node_file=open(rrd+'node','r')
            for addr in node_file:
                try:
                    self.mainDoc.RegisterNode(addr.rstrip())
                except socket.error:
                    self.log.info("Can not connect node %s"%addr)
                    pass
            node_file.close()
            os.remove(rrd+'node')


    def sig_handler (self, sig, frame):
        """ Signal Handler"""
        print "Close main server"
        self.delete_window()


    def HandleRequest(self, view, **aList):
        self.viewToDoc[view].HandleRequest(aList)

    def CheckEnv(self):
        """ Check environment to make sure every file are there """

        if not os.path.isdir(self.config.rrd_path):
            #make rrd and png dir
            os.makedirs(self.config.rrd_path+'png/')
        #if can not find cluster in user section, add it.
        try:
            self.config.read_desc(self.config.cluster_name)
        except PConfigNoUser:
            self.config.add_user(self.config.cluster_name,'Cluster')

        #Create missing rrd file
        path=self.config.rrd_path
        if not os.path.exists(path+self.config.cluster_name+'.rrd'):
            self.rrd.create_user(self.config.cluster_name)
        for item in self.config.check_rrd_exist():
            self.rrd.create_user(item)


